#ifndef _INNERAPI_H_CSEAPI_
#define _INNERAPI_H_CSEAPI_

#include "CseApi/platform.h"
#include "CseApi/lockers.h"
#include "files.h"

#include "CseApi/IntObj.h"
#include "CseApi/WIntObj.h"
#include "CseApi/FloatObj.h"

#include "CseApi/MemBlock.h"

#define CSE_ARRAY_LEN(x)           (*(TUint32 *)((char *)x - sizeof(TUint32)))

#include "CseApi/CharArray.h"
#include "CseApi/IntArray.h"
#include "CseApi/InstantProp.h"
#include "CseApi/ObjArray.h"
#include "CseApi/EntryArray.h"

extern void LogErrNameAndDesc(const TCharArray& name, const TCharArray& desc);
extern void Cse_SpecialFree(PEntryPoint pEntry, CseObj key, TUint32 hash);

// Declare BaseTypes.h
//==============================================================================
#include "CseApi/BaseTypes.h"

#define CSEOBJ_TYPE_OFFSET         sizeof(TInt32)
#define CSEOBJ_INNER_OFFSET        (sizeof(TInt32) + sizeof(TUint32))

// CSE Object flag
#define CSEOBJ_LINKED              11  // bit11, Instance, linked CSE data
#define CSEOBJ_FREE_FLAG           14  // bit14, all data type
#define CSEOBJ_STR_FLAG            15  // bit15, all data type

#define CSE_ATOMCALL_FLAG          (dtNotator + dtWeak)

#define CSE_UNDESC_ERROR           _T("undescribed error")

void BaseTypes_init(void);
void BaseTypes_exit(void);

//------------------------------------------------------------------------------
void Cse_IncRef(CseObj obj);
void Cse_DecRef(CseObj obj);
CseObj Cse_IncRefEx(CseObj obj);
TUint32 Cse_RefCount(CseObj obj);

int Cse_type(CseObj obj);
int Cse_len(CseObj value);
TBool Cse_FixSize(CseObj value, int iResvd);
TUint32 Cse_hash(CseObj obj);
TInt Cse_ObjComp(CseObj obj1, CseObj obj2, int tp2);
TInt Cse_compare(CseObj self, CseObj other);
TBool Cse_equal(CseObj self, CseObj other);

TInt32 Cse_GetFlag(CseObj obj);
void Cse_SetFlag(CseObj obj, TInt32 flag);
TBool Cse_OptionOn(CseObj value, int iOffset);
void Cse_SetOption(CseObj value, int iOffset);
void Cse_ClearOption(CseObj value, int iOffset);

CseObj Cse_unlink(CseObj value);

void Cse_str(TCharArray& ret, CseObj value);
void Cse_StrEx(CseObj sOut, CseObj value);
void Cse_BeStr(TCharArray& ret, CseObj obj);

//------------------------------------------------------------------------------
CseObj CseInt_new(TInt initVal, TInt flag=0);
CseObj CseWint_new(TWint initVal);
CseObj CseFloat_new(TDouble initVal);

CseObj CseStr_new(const TXchar *sValue, int iLen=-1);
CseObj CseStr_new(const TCharArray& sValue);
CseObj CseStr_NewEx(TCharArray& sValue);
TXchar CseStr_append(CseObj str, TXchar ch, int *pIndex=NULL);
TXchar CseStr_get(CseObj str, int index);
void CseStr_set(CseObj str, int index, TXchar ch);
void CseStr_insert(CseObj str, int index, TXchar ch);
CseObj CseStr_slice(CseObj str, int index, int count);
void CseStr_remove(CseObj str, int index, int count=1);
void CseStr_clear(CseObj str);
void CseStr_assign(CseObj TargStr, const TCharArray& SourStr);
void CseStr_assign(CseObj TargStr, CseObj SourStr);
void CseStr_join(CseObj TargStr, const TCharArray& SourStr, int index=0);
void CseStr_join(CseObj TargStr, CseObj SourStr, int index=0);
int CseStr_SortAdd(CseObj str, TXchar ch);
void CseStr_sort(CseObj str);
void CseStr_upper(CseObj str);
void CseStr_lower(CseObj str);
void CseStr_trim(CseObj str);
void CseStr_TrimLeft(CseObj str);
void CseStr_TrimRight(CseObj str);
void CseStr_truncate(CseObj str, int iLen);
TUint32 CseStr_hash(CseObj str);
int CseStr_find(CseObj str, TXchar ch, TBool fromEnd=false);
int CseStr_find(CseObj str, const TXchar *sSub, int from=0);
CseObj CseStr_ToInt(CseObj str);
CseObj CseStr_ToWInt(CseObj str);
CseObj CseStr_ToDouble(CseObj str);

CseObj CseTier_new(int iSize);
CseObj CseTier_new(const TIntArray& tValue);
CseObj CseTier_NewEx(TIntArray& tValue);
TInt CseTier_append(CseObj tier, TInt value, int *pIndex=NULL);
TInt CseTier_get(CseObj tier, int index);
void CseTier_set(CseObj tier, int index, TInt value);
void CseTier_insert(CseObj tier, int index, TInt value);
CseObj CseTier_slice(CseObj tier, int index, int count);
void CseTier_remove(CseObj tier, int index, int count=1);
void CseTier_clear(CseObj tier);
void CseTier_assign(CseObj TargTier, const TIntArray& SourTier);
void CseTier_assign(CseObj TargTier, CseObj SourTier);
void CseTier_join(CseObj TargTier, const TIntArray& SourTier, int index=0);
void CseTier_join(CseObj TargTier, CseObj SourTier, int index=0);
int CseTier_SortAdd(CseObj tier, TInt value);
void CseTier_sort(CseObj tier);
void CseTier_truncate(CseObj tier, int iLen);

CseObj CseBuff_new(int iSize);
CseObj CseBuff_new(const TObjArray& bValue);
CseObj CseBuff_NewEx(TObjArray& bValue);
CseObj CseBuff_StolenAppend(CseObj buff, CseObj obj);
CseObj CseBuff_append(CseObj buff, CseObj obj, int *pIndex=NULL);
CseObj CseBuff_get(CseObj buff, int index);
void CseBuff_set(CseObj buff, int index, CseObj value);
void CseBuff_insert(CseObj buff, int index, CseObj value);
CseObj CseBuff_slice(CseObj buff, int index, int count);
void CseBuff_remove(CseObj buff, int index, int count=1);
void CseBuff_clear(CseObj buff);
void CseBuff_assign(CseObj TargBuff, const TObjArray& SourBuff);
void CseBuff_assign(CseObj TargBuff, CseObj SourBuff);
void CseBuff_join(CseObj TargBuff, const TObjArray& SourBuff, int index=0);
void CseBuff_join(CseObj TargBuff, CseObj SourBuff, int index=0);
int CseBuff_SortAdd(CseObj buff, CseObj obj);
void CseBuff_sort(CseObj buff);
void CseBuff_truncate(CseObj buff, int iLen);
CseObj CseBuff_ToNotator(CseObj buff, int index=0);

CseObj CseDict_new(int size=8);
CseObj CseDict_new(const TEntryArray& entry);
CseObj CseDict_NewEx(TEntryArray& entry);
CseObj CseDict_EntryValue(CseObj dict, CseObj key);
PEntryPoint CseDict_IdEntry(CseObj dict, const TCharArray& sId, TUint32 hash);
CseObj CseDict_IdEntryValue(CseObj dict, const TCharArray& sId, TUint32 hash);
CseObj CseDict_StolenSet(CseObj dict, CseObj key, CseObj value);
void CseDict_set(CseObj dict, CseObj key, CseObj value);
CseObj CseDict_SetEx(CseObj dict, CseObj key, CseObj value);
void CseDict_clear(CseObj dict);
void CseDict_assign(CseObj TargDict, const TEntryArray& SourDict);
void CseDict_assign(CseObj TargDict, CseObj SourDict);
void CseDict_join(CseObj TargDict, const TEntryArray& SourDict);
void CseDict_join(CseObj TargDict, CseObj SourDict);
CseObj CseDict_StolenBind(CseObj dict, CseObj value);
void CseDict_bind(CseObj dict, CseObj value);
CseObj CseDict_GetBinding(CseObj dict);
TBool CseDict_enumItem(CseObj dict, PEntryPoint& pEntry);

CseObj CseNotator_new(CseObj NotatorId);

CseObj CseStrong_new(CseObj initVal, TInt flag=0);
CseObj CseStrong_StolenSet(CseObj strong, CseObj value);
void CseStrong_set(CseObj strong, CseObj value);

CseObj CseId_new(const TCharArray& sValue);
CseObj CseId_NewEx(TCharArray& sValue);
CseObj CseWeak_new(CseObj initVal, TInt flag=0);

CseObj CseInstance_new();
CseObj CseInstance_AsKey(CseObj obj);
CseObj CseInstance_MapVar(TXchar flag, va_list& pArg);

//------------------------------------------------------------------------------
TBool CseRegist_exist(const TCharArray& key);
CseObj CseRegist_get(const TCharArray& key);
CseObj CseRegist_StolenSet(const TCharArray& key, CseObj value);
CseObj CseRegist_set(const TCharArray& key, CseObj value);
void CseRegist_delete(const TCharArray& key);

void CseRegist_hold(CseObj value);
CseObj CseRegist_StolenHold(CseObj value);

// Declare CseObj.h
//==============================================================================
#include "CseApi/CseObj.h"

// Declare modules.h
//==============================================================================
#include "CseApi/modules.h"

TBool Cse_SearchFile(TCharArray& ret, const TCharArray& sModule, const TCharArray& RefFile=CseEmptyStr);
CseObj Cse_GetModule(const TCharArray& sModule, TBool OnlyTopLevel=false);
void Cse_SetModule(const TCharArray& sModule, CseObj module);
CseObj Cse_LoadCsd(const TCharArray& sModule, const TCharArray& RefFile=CseEmptyStr);
TBool Cse_UseModule(CseObj TargModule, CseObj SourModule);
void Cse_UnloadModules(TBool safeExit);

CseObj Cse_NewModule(const TCharArray& sModule);
TBool Cse_AddSubModule(CseObj owner, const TCharArray& name, CseObj SubModule);

extern CseObj constSpace;
extern CseObj CppVoidFunc;
extern CseObj CppStrType;

#endif
